package com.lanhe.order.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lanhe.common.constant.Constants;
import com.lanhe.common.constant.HttpStatus;
import com.lanhe.common.core.domain.entity.LhMemberBase;
import com.lanhe.common.exception.ServiceException;
import com.lanhe.common.utils.DateUtils;
import com.lanhe.common.utils.StringUtils;
import com.lanhe.common.utils.wechat.WxTiXianUtil;
import com.lanhe.member.domain.LhMemberWithdrawalRec;
import com.lanhe.member.service.ILhMemberBaseService;
import com.lanhe.member.service.ILhMemberWithdrawalRecService;
import com.lanhe.order.domain.LhOrdersWithdrawal;
import com.lanhe.order.mapper.LhOrdersWithdrawalMapper;
import com.lanhe.order.service.ILhOrdersWithdrawalService;
import com.lanhe.weichatTransfer.domain.LhOrdersWeichatTransfer;
import com.lanhe.weichatTransfer.service.ILhOrdersWeichatTransferService;
import com.wechat.pay.java.service.transferbatch.TransferBatchService;
import com.wechat.pay.java.service.transferbatch.model.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 用户提现申请(LhOrdersWithdrawal)表服务实现类
 *
 * @author zhanggl
 * @since 2024-01-05 21:35:20
 */
@Service
public class LhOrdersWithdrawalServiceImpl extends ServiceImpl<LhOrdersWithdrawalMapper, LhOrdersWithdrawal> implements ILhOrdersWithdrawalService {

	@Value("${lanhe.wechat.appid}")
	private String appid;

	@Autowired
	private LhOrdersWithdrawalMapper lhOrdersWithdrawalMapper;

	@Autowired
	private ILhMemberBaseService lhMemberBaseService;

	@Autowired
	private ILhMemberWithdrawalRecService withdrawalRecordsService;

	@Autowired
	private ILhOrdersWeichatTransferService lhOrdersWeichatTransferService;

	@Autowired
	private WxTiXianUtil wxTiXianUtil;

	/**
	 * 分页查询所有数据
	 *
	 * @param lhOrdersWithdrawal 实体
	 * @return java.util.List<com.lanhe.order.domain.LhOrdersWithdrawal>
	 * @author zhanggl
	 * @date 2024/1/5
	 */
	@Override
	public List<LhOrdersWithdrawal> selectOrdersWithdrawalList(LhOrdersWithdrawal lhOrdersWithdrawal) {
		LambdaQueryWrapper<LhOrdersWithdrawal> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(StringUtils.isNotBlank(lhOrdersWithdrawal.getOrderNumber()), LhOrdersWithdrawal::getOrderNumber, lhOrdersWithdrawal.getOrderNumber());
		queryWrapper.eq(ObjectUtil.isNotNull(lhOrdersWithdrawal.getPayed()), LhOrdersWithdrawal::getPayed, lhOrdersWithdrawal.getPayed());
		queryWrapper.eq(ObjectUtil.isNotNull(lhOrdersWithdrawal.getAuditStatus()), LhOrdersWithdrawal::getAuditStatus, lhOrdersWithdrawal.getAuditStatus());
		queryWrapper.ge(ObjectUtil.isNotNull(lhOrdersWithdrawal.getBeginTime()), LhOrdersWithdrawal::getCreateTime, lhOrdersWithdrawal.getBeginTime());
		queryWrapper.le(ObjectUtil.isNotNull(lhOrdersWithdrawal.getEndTime()), LhOrdersWithdrawal::getCreateTime, lhOrdersWithdrawal.getEndTime());
		queryWrapper.eq(ObjectUtil.isNotNull(lhOrdersWithdrawal.getMemberId()), LhOrdersWithdrawal::getMemberId, lhOrdersWithdrawal.getMemberId());
		queryWrapper.orderByDesc(LhOrdersWithdrawal::getOrderId);
		return lhOrdersWithdrawalMapper.selectList(queryWrapper);
	}

	/**
	 * 根据ID查询订单
	 *
	 * @param orderId 订单ID
	 * @return com.lanhe.order.domain.LhOrdersWithdrawal
	 * @author zhanggl
	 * @date 2024/1/5
	 */
	@Override
	public LhOrdersWithdrawal selectOrdersWithdrawalById(Long orderId) {
		return lhOrdersWithdrawalMapper.selectById(orderId);
	}

	/**
	 * 审核
	 *
	 * @param ordersWithdrawal 实体
	 * @return int
	 * @author zhanggl
	 * @date 2024/1/5
	 */
	@Override
	@Transactional
	public int auditOrdersWithdrawalById(LhOrdersWithdrawal ordersWithdrawal) {

		LhOrdersWithdrawal lhOrdersWithdrawal = selectOrdersWithdrawalById(ordersWithdrawal.getOrderId());
		if (ObjectUtil.isNull(lhOrdersWithdrawal)) {
			throw new ServiceException("查询提现订单异常", HttpStatus.ERROR);
		}

		LhMemberBase lhMemberBase = lhMemberBaseService.getById(lhOrdersWithdrawal.getMemberId());
		if (ObjectUtil.isNull(lhMemberBase)) {
			throw new ServiceException("查询用户信息异常", HttpStatus.ERROR);
		}
		if (ObjectUtil.isNull(lhMemberBase.getLockAmount())){
			throw new ServiceException("锁定金额异常", HttpStatus.ERROR);
		}
		if (lhOrdersWithdrawal.getAmount().compareTo(lhMemberBase.getLockAmount()) > 0) {
			throw new ServiceException("用户锁定金额异常", HttpStatus.ERROR);
		}

		// 通过
		if (Constants.ORDERS_WITHDRAWAL_STATUS_2.equals(ordersWithdrawal.getAuditStatus())) {

			// 更新会员余额+释放锁定
			lhMemberBaseService.updateMemberBaseBalance(lhOrdersWithdrawal.getMemberId(), lhOrdersWithdrawal.getAmount(), Constants.ORDERS_WITHDRAWAL_STATUS_2);

			// 增加记录
			LhMemberWithdrawalRec memberWithdrawalRecords = new LhMemberWithdrawalRec();
			memberWithdrawalRecords.setOrderNumber(lhOrdersWithdrawal.getOrderNumber());
			memberWithdrawalRecords.setMemberId(lhOrdersWithdrawal.getMemberId());
			memberWithdrawalRecords.setAmount(lhOrdersWithdrawal.getAmount());
			memberWithdrawalRecords.setMemberBalance(lhMemberBase.getBalance());
			withdrawalRecordsService.insertWithdrawalRecords(memberWithdrawalRecords);

		} else {
			// 更新会员余额+释放锁定
			lhMemberBaseService.updateMemberBaseBalance(lhOrdersWithdrawal.getMemberId(), lhOrdersWithdrawal.getAmount(), Constants.ORDERS_WITHDRAWAL_STATUS_3);
		}

		// 更新提现订单状态
		LhOrdersWithdrawal orders = new LhOrdersWithdrawal();
		orders.setOrderId(lhOrdersWithdrawal.getOrderId());
		orders.setAuditStatus(ordersWithdrawal.getAuditStatus());
		return updateOrdersWithdrawal(orders);
	}

	/**
	 * 修改
	 *
	 * @param ordersWithdrawal 实体
	 * @return int
	 * @author zhanggl
	 * @date 2024年01月05日22:30:49
	 */
	public int updateOrdersWithdrawal(LhOrdersWithdrawal ordersWithdrawal) {
		LambdaQueryWrapper<LhOrdersWithdrawal> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(LhOrdersWithdrawal::getOrderId, ordersWithdrawal.getOrderId());

		ordersWithdrawal.setAuditStatus(ordersWithdrawal.getAuditStatus());
		ordersWithdrawal.setUpdateTime(new Date());
		return lhOrdersWithdrawalMapper.updateById(ordersWithdrawal);
	}

	/**
	 * 设为已支付
	 *
	 * @param ordersWithdrawal 实体
	 * @return int
	 * @author zhanggl
	 * @date 2024/1/5
	 */
	@Override
	@Transactional
	public int setPayed(LhOrdersWithdrawal ordersWithdrawal) {
		LambdaQueryWrapper<LhOrdersWithdrawal> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(LhOrdersWithdrawal::getOrderId, ordersWithdrawal.getOrderId());

		ordersWithdrawal.setPayed(ordersWithdrawal.getPayed());
		ordersWithdrawal.setPayedTime(new Date());
		ordersWithdrawal.setUpdateTime(new Date());
		return lhOrdersWithdrawalMapper.updateById(ordersWithdrawal);
	}

	/**
	 * 提现申请
	 *
	 * @param ordersWithdrawal 实体
	 * @return int
	 * @author zhanggl
	 * @date 2024/1/5
	 */
	@Override
	@Transactional
	public int insertOrdersWithdrawal(LhOrdersWithdrawal ordersWithdrawal) {

		if (ordersWithdrawal.getAmount().compareTo(new BigDecimal(10))<0) {
			throw new ServiceException("提现余额必须大于10", HttpStatus.ERROR);
		}

		LhMemberBase memberBase = lhMemberBaseService.getById(ordersWithdrawal.getMemberId());
		if (ordersWithdrawal.getAmount().compareTo(memberBase.getBalance())>0) {
			throw new ServiceException("余额不足,不能提现", HttpStatus.ERROR);
		}
		// 如果是支付宝就添加手机号和用户名
		if ("2".equals(ordersWithdrawal.getIsZfb())){
			ordersWithdrawal.setZfbName(ordersWithdrawal.getZfbName());
			ordersWithdrawal.setZfbMobile(ordersWithdrawal.getZfbMobile());
		}
		ordersWithdrawal.setOrderNumber(DateUtils.generateOrderCode());
		ordersWithdrawal.setWxId(memberBase.getWxId());
		ordersWithdrawal.setAmount(ordersWithdrawal.getAmount());
		ordersWithdrawal.setAuditStatus(Constants.ORDERS_WITHDRAWAL_STATUS_1);
		ordersWithdrawal.setPayed(Constants.PAYED_NO);
		ordersWithdrawal.setCreateTime(new Date());
		lhOrdersWithdrawalMapper.insert(ordersWithdrawal);

		// 更新用户信息，减去余额，增加冻结金额
		return lhMemberBaseService.updateLhMemberBalance(ordersWithdrawal.getMemberId(), ordersWithdrawal.getAmount());
	}


	void wexinAudit(LhOrdersWithdrawal lhOrdersWithdrawal,String batchNo,String outDetailNo){
		/**
		 * 判断订单有没有问题
		 *
		 */
		if (ObjectUtil.isNull(lhOrdersWithdrawal)) {
			throw new ServiceException("查询提现订单异常", HttpStatus.ERROR);
		}

		LhMemberBase lhMemberBase = lhMemberBaseService.getById(lhOrdersWithdrawal.getMemberId());
		if (ObjectUtil.isNull(lhMemberBase)) {
			throw new ServiceException("查询用户信息异常", HttpStatus.ERROR);
		}
		if (ObjectUtil.isNull(lhMemberBase.getLockAmount())){
			throw new ServiceException("锁定金额异常", HttpStatus.ERROR);
		}
		if (lhOrdersWithdrawal.getAmount().compareTo(lhMemberBase.getLockAmount()) > 0) {
			throw new ServiceException("用户锁定金额异常", HttpStatus.ERROR);
		}

		//更新数据
		// 更新会员余额+释放锁定
		lhMemberBaseService.updateMemberBaseBalance(lhOrdersWithdrawal.getMemberId(), lhOrdersWithdrawal.getAmount(), Constants.ORDERS_WITHDRAWAL_STATUS_2);

		// 增加记录
		LhMemberWithdrawalRec memberWithdrawalRecords = new LhMemberWithdrawalRec();
		memberWithdrawalRecords.setOrderNumber(lhOrdersWithdrawal.getOrderNumber());
		memberWithdrawalRecords.setMemberId(lhOrdersWithdrawal.getMemberId());
		memberWithdrawalRecords.setAmount(lhOrdersWithdrawal.getAmount());
		memberWithdrawalRecords.setMemberBalance(lhMemberBase.getBalance());
		memberWithdrawalRecords.setReason("微信转账");
		memberWithdrawalRecords.setOutDetailNo(outDetailNo);
		memberWithdrawalRecords.setBatchNo(batchNo);
		withdrawalRecordsService.insertWithdrawalRecords(memberWithdrawalRecords);

// 更新提现订单状态
		LhOrdersWithdrawal orders = new LhOrdersWithdrawal();
		orders.setOrderId(lhOrdersWithdrawal.getOrderId());
		orders.setAuditStatus(Constants.ORDERS_WITHDRAWAL_STATUS_2);
		updateOrdersWithdrawal(orders);
	}


	/**
	 * 批量微信支付
	 * @param ids
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public int setWeiXinPayed(Long[] ids) {
		// 批次的名称
		String batchNoName = DateUtil.now();
		// 商家次批号
		String batchNo = wxTiXianUtil.getBatchNo();
		LambdaQueryWrapper<LhOrdersWithdrawal> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(LhOrdersWithdrawal::getOrderId, ids);
		List<LhOrdersWithdrawal> lhOrdersWithdrawals = lhOrdersWithdrawalMapper.selectList(queryWrapper);
		List<TransferDetailInput> detailInputs = new ArrayList<>();
		Long totalAmount = 0l;     // 总金额


		int totalNum = 0;
		for (LhOrdersWithdrawal lhOrdersWithdrawal : lhOrdersWithdrawals) {

			String outDetailNo = batchNo+totalNum++;

			TransferDetailInput transferDetailInput = new TransferDetailInput();
			transferDetailInput.setOpenid(lhOrdersWithdrawal.getWxId());
			BigDecimal userAmount = lhOrdersWithdrawal.getAmount().multiply(new BigDecimal(100));
			long amount = userAmount.longValue();
			totalAmount += amount;
			transferDetailInput.setTransferAmount(amount);
			transferDetailInput.setTransferRemark("微信api转账");
			transferDetailInput.setOutDetailNo(outDetailNo);
			detailInputs.add(transferDetailInput);
			/**
			 * 		转账记录
			 */
			// 微信审核
			wexinAudit(lhOrdersWithdrawal,batchNo,outDetailNo);
			System.err.println("transferDetailInput "+transferDetailInput.toString());


		}
		String today = DateUtils.parseDateToStr("yyyy年MM月dd日",new Date());
		String batchName = today+"提现单";

		// 微信提现
		TransferBatchService service = wxTiXianUtil.config();

		InitiateBatchTransferRequest request = new InitiateBatchTransferRequest();
		request.setAppid(appid);
		request.setOutBatchNo(batchNo);
		//批次名称
		request.setBatchName(batchName);
		// 备注
		request.setBatchRemark(batchName);
		//转账总金额
		request.setTotalAmount(totalAmount);
		//转账总笔数
		request.setTotalNum(detailInputs.size());
		//转账明细列表
		request.setTransferDetailList(detailInputs);
		InitiateBatchTransferResponse response = service.initiateBatchTransfer(request);

		String batchId = response.getBatchId();
		if(StringUtils.isBlank(batchId)){
			throw new ServiceException("微信提现异常", HttpStatus.ERROR);
		}
		String createTime = response.getCreateTime();
		if (StringUtils.isBlank(createTime)){
			throw new ServiceException("微信提现异常", HttpStatus.ERROR);
		}
		String outBatchNo = response.getOutBatchNo();
		if (StringUtils.isBlank(outBatchNo)){
			throw new ServiceException("微信提现异常", HttpStatus.ERROR);
		}
		String batchStatus = response.getBatchStatus();
		if (StringUtils.isBlank(batchStatus)){
			throw new ServiceException("微信提现异常", HttpStatus.ERROR);
		}

		LhOrdersWeichatTransfer weichatTransfer = new LhOrdersWeichatTransfer();
		weichatTransfer.setBatchTransferId(System.currentTimeMillis());
		BeanUtils.copyProperties(request,weichatTransfer);
		weichatTransfer.setBatchId(batchId);
		weichatTransfer.setBatchStatus(batchStatus);
		return lhOrdersWeichatTransferService.insertLhOrdersWeichatTransfer(weichatTransfer);
	}
}

